import { getCenter } from '../../../../mapUtils/GeometryUtil';
import { projectWebMercatorToLngLat } from '../../../../mapUtils/CoordinateUtil';
import { randomUUID } from '../../../../mapUtils/RandomUtil';

/**
 * 树形区域组件
 */
class RegionTree {
  constructor(_) {
    this.tool = _;
    this.id = randomUUID();
    this.layeridPrefix = _.layeridPrefix + '_Tree_';
    this.style = {
      1: { 'line-width': 6, 'line-opacity': 1 },
      2: { 'line-width': 3, 'line-opacity': 1 },
      3: { 'line-width': 1, 'line-opacity': 0.2 }
    };
    this.highlightStyle = { sourceType: 'LineString', width: 5, color: 'rgb(15,255,255)' };
    this._onClick = this.onClick.bind(this);
    this._onMousemove = this.onMousemove.bind(this);
    this._onContextmenu = this.onContextmenu.bind(this);
    this.regionFeatures = {};
    this.renderedFeatures = [];
    this.selectedArea = null;
    this.events = {
      onChange: () => { }
    };
    this.init();
  }

  /**
   * 获取地图对象
   * @ignore
   */
  getMap() {
    return this.tool.getMap();
  }

  /**
   * 获取工具箱
   * @param {String} toolname 工具箱名称
   * @ignore
   */
  getTool(toolname) {
    return this.tool.getTool(toolname);
  }

  /**
   * 设置事件方法
   * @param {*} _events 事件方法
   */
  setEvents(_events) {
    for (let key in _events) {
      this.events[key] = _events[key];
    }
  }

  /**
   * 初始化
   * @ignore
   */
  init() {
    this.initId();
    this.initLayer();
  }

  /**
   * 加载区域树形结构
   * @param {Array} datas 区域图形数据
   * @param {*} events 区域事件
   * @param {*} selected 默认选中区域
   */
  render(datas, events, selected) {
    if (events) {
      this.setEvents(events);
    }
    this.formatData(datas);
    let defaultFeature = this.regionFeatures[datas[0].qyfl][0];
    if (selected) {
      let feature = this.regionFeatures[selected.qyfl].find((item) => item.properties.oid === selected.oid);
      if (feature) {
        defaultFeature = feature;
      }
    }
    this.selectArea(defaultFeature);
    this.getMap().on('click', this._onClick);
    this.getMap().on('mousemove', this._onMousemove);
    this.getMap().on('contextmenu', this._onContextmenu);
  }

  /**
   * 格式化数据
   * @param {Array} datas 区域图形数据
   */
  formatData(datas) {
    this.regionFeatures = [];
    datas.forEach((item) => {
      let geometry = JSON.parse(item.geometry);
      geometry.coordinates = projectWebMercatorToLngLat(geometry.coordinates);
      let feature = turf.feature(geometry, Object.assign({
        oid: item.oid,
        qyfl: item.qyfl,
        qybh: item.qybh,
        qymc: item.qymc,
        sjqy: item.sjqy,
        mj: item.mj
      }, this.tool.getStyleByQyfl(item.qyfl)));
      if (this.regionFeatures[item.qyfl]) {
        this.regionFeatures[item.qyfl].push(feature);
      } else {
        this.regionFeatures[item.qyfl] = [feature];
      }
    });
  }

  /**
   * 选择区域
   * @param {feature} feature 区域数据
   */
  selectArea(feature) {
    this.getTool('HighlightTool').unhighlight();
    this.selectedArea = feature;
    this.renderedFeatures = this.getShowFeatures();
    let featureCollection = turf.featureCollection(this.renderedFeatures);
    this.getMap().getSource(this._sourceId).setData(featureCollection);
    this.getTool('BaseMapTool').fitBounds(turf.bbox(turf.envelope(featureCollection)));
    if(this.events.onChange) {
      this.events.onChange(feature);
    }
  }

  /**
   * 获取展示图形数据
   */
  getShowFeatures() {
    let topQyfl = this.selectedArea.properties.qyfl;
    this.selectedArea.properties = Object.assign(this.selectedArea.properties, this.style[1]);
    let features = [this.selectedArea, turf.point(getCenter(this.selectedArea.geometry), {
      qymc: this.selectedArea.properties.qymc,
      qyfl: this.selectedArea.properties.qyfl,
      color: this.selectedArea.properties['line-color']
    })];
    let secondFeaturesIds = [];
    if (topQyfl < 5 && this.regionFeatures[topQyfl + 1]) {
      let secondFeatures = this.regionFeatures[topQyfl + 1].filter((item) => {
        if (item.properties.sjqy === this.selectedArea.properties.oid) {
          secondFeaturesIds.push(item.properties.oid);
          item.properties = Object.assign(item.properties, this.style[2]);
          features.push(turf.point(getCenter(item.geometry), {
            qymc: item.properties.qymc,
            qyfl: item.properties.qyfl,
            color: item.properties['line-color']
          }));
          return item;
        }
      });
      features = secondFeatures.concat(features);
    }
    if (topQyfl < 4 && this.regionFeatures[topQyfl + 2]) {
      let thirdFeatures = this.regionFeatures[topQyfl + 2].filter((item) => {
        if (secondFeaturesIds.indexOf(item.properties.sjqy) > -1) {
          item.properties = Object.assign(item.properties, this.style[3]);
          return item;
        }
      });
      features = thirdFeatures.concat(features);
    }
    return features;
  }

  /**
   * 刷新图层
   */
  refresh() {
    this.renderedFeatures.forEach((feature) => {
      let style = this.tool.getStyleByQyfl(feature.properties.qyfl);
      feature.properties['line-color'] = style['line-color'];
    });
    this.getMap().getSource(this._sourceId).setData(turf.featureCollection(this.renderedFeatures));
  }

  /**
   * 清空图层
   */
  clear() {
    this.regionFeatures = {};
    this.getMap().getSource(this._sourceId).setData(turf.featureCollection([]));
  }

  /**
   * 删除图层
   */
  remove() {
    this.selectedArea = null;
    this.getTool('HighlightTool').unhighlight();
    this.getMap().removeLayer(this._polygonLayerId);
    this.getMap().removeLayer(this._strokeLayerId);
    this.getMap().removeLayer(this._labelLayerId);
    this.getMap().removeSource(this._sourceId);
    this.getMap().off('click', this._onClick);
    this.getMap().off('mousemove', this._onMousemove);
    this.getMap().off('contextmenu', this._onContextmenu);
  }

  /**
   * 鼠标点击事件
   * @param {*} e 事件参数
   * @ignore
   */
  onClick(e) {
    let feature = this.queryUnderFeatures(e);
    if (feature) {
      this.selectArea(feature);
    }
  }

  /**
   * 鼠标移动事件
   * @param {*} e 事件参数
   * @ignore
   */
  onMousemove(e) {
    let feature = this.queryUnderFeatures(e);
    if (feature) {
      if (this.highlightAreaId !== feature.properties.oid) {
        this.highlightAreaId = feature.properties.oid;
        feature = turf.feature(feature.geometry, {
          sourceType: 'Polygon',
          color: feature.properties['line-color'],
          opacity: 0.3
        });
        this.getTool('HighlightTool').highlight([feature]);
      }
    } else {
      this.highlightAreaId = null;
      this.getTool('HighlightTool').unhighlight();
    }
  }

  /**
   * 鼠标右击事件
   * @ignore
   */
  onContextmenu() {
    let prevQyfl = this.selectedArea.properties.qyfl - 1;
    if (this.regionFeatures[prevQyfl]) {
      let feature = this.regionFeatures[prevQyfl].find((item) => item.properties.oid === this.selectedArea.properties.sjqy);
      this.selectArea(feature);
    }
  }

  /**
   * 查询可见图层中，与查询条件匹配的要素数组
   * @param {*} e 查询条件
   * @ignore
   */
  queryUnderFeatures(e) {
    let features = this.getMap().queryRenderedFeatures(e.point, { layers: [this._polygonLayerId] });
    let nextQyfl = this.selectedArea.properties.qyfl + 1;
    let feature = features.find((item) => item.properties.qyfl === nextQyfl);
    if (feature) {
      let data = this.regionFeatures[nextQyfl].find((item) => item.properties.oid === feature.properties.oid);
      return data;
    }
    return feature;
  }

  /**
   * 初始化图层Id
   * @ignore
   */
  initId() {
    // 数据源
    this._sourceId = this.layeridPrefix + '_source_' + this.id;
    // 图层
    this._polygonLayerId = this.layeridPrefix + '_Polygon' + this.id;
    this._strokeLayerId = this.layeridPrefix + '_PolygonStroke' + this.id;
    this._labelLayerId = this.layeridPrefix + '_PolygonLabel' + this.id;
  }

  /**
   * 初始化图层
   * @ignore
   */
  initLayer() {
    // 初始化数据源
    if(!this.tool.getMap().getSource(this._sourceId)) {
      this.tool.getMap().addSource(this._sourceId, {
        type: 'geojson',
        data: {
          type: 'FeatureCollection',
          features: []
        }
      });
    }
    // 初始化图层
    if(!this.tool.getMap().getLayer(this._polygonLayerId)) {
      this.tool.getMap().addLayer({
        id: this._polygonLayerId,
        type: 'fill',
        source: this._sourceId,
        filter: ['all', ['==', '$type', 'Polygon']],
        paint: {
          'fill-color': ['get', 'color'],
          'fill-opacity': ['get', 'opacity']
        }
      });
    }
    if(!this.tool.getMap().getLayer(this._strokeLayerId)) {
      this.tool.getMap().addLayer({
        id: this._strokeLayerId,
        type: 'line',
        source: this._sourceId,
        filter: ['all', ['==', '$type', 'Polygon']],
        paint: {
          'line-color': ['get', 'line-color'],
          'line-opacity': ['get', 'line-opacity'],
          'line-width': ['get', 'line-width']
        }
      });
    }
    if(!this.tool.getMap().getLayer(this._labelLayerId)) {
      this.tool.getMap().addLayer({
        id: this._labelLayerId,
        type: 'symbol',
        source: this._sourceId,
        filter: ['all', ['==', '$type', 'Point']],
        layout: {
          'text-field': '{qymc}',
          'text-size': 12,
          'text-font': ['Microsoft YaHei Regular'],
          'text-allow-overlap': true,
          'text-max-width': 8
        },
        paint: {
          'text-color': ['get', 'color']
        }
      });
    }
  }
}

export default RegionTree;
